home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / hpcdtoppm.tproj / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-22  |  13.5 KB  |  674 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
  2. *  Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12.  
  13.  
  14. uBYTE sbuffer[SECSIZE];
  15.  
  16. enum SIZES  size     = S_UNSPEC;
  17. enum CORR   corrmode = C_UNSPEC;
  18.  
  19. sINT do_info;
  20. sINT do_melde;
  21. sINT bufpos=0;
  22.  
  23. char *pcdname=0,*ppmname=0;
  24. static FILE  *fin=0,*fout=0;
  25.  
  26. static implane Luma, Chroma1,Chroma2;
  27. static implane *PLuma,*PChroma1,*PChroma2;
  28. static sINT    emulate_seek=0;
  29. static sINT    print_pos;
  30.  
  31. static char    dir64[512];
  32. static void    get_dir64(void);
  33.  
  34. #define PrintPos(x) {if(print_pos) fprintf(stderr,"File-Offset: %8d = %8x (hex) = %d (sec)\n",(x),(x),(x)/0x800);}
  35.  
  36. static void checkin(void);
  37. static void parseargs(int,char**);
  38. static void sizecontrol(sizeinfo *,dim,dim);
  39. static void f_1 (dim,dim,sINT);
  40. static void f_4 (dim,dim,sINT);
  41. static void f_5 (dim,dim);
  42. static void f_6 (dim,dim);
  43.  
  44.  
  45. void close_all(void)
  46.  {
  47.   if(fin && (fin != stdin)) fclose(fin);
  48.  
  49.   if(fout)
  50.    {if(fout==stdout) 
  51.       fflush(fout);
  52.     else 
  53.       fclose(fout);
  54.    }
  55.  }
  56.  
  57.  
  58.  
  59. void main(int argc,char **argv)
  60.  {
  61.  
  62.   typecheck();
  63.  
  64.   do_info=0;
  65.   do_melde=0;
  66.   print_pos=0;
  67.  
  68.   parseargs(argc,argv);
  69.  
  70.   if(size     == S_UNSPEC) size     = S_DEFAULT;
  71.   if(corrmode == C_UNSPEC) corrmode = C_DEFAULT;
  72.  
  73.   if(print_pos   && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  74.   if(do_info     && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  75.  
  76.  
  77.   if(strcmp(pcdname,"-"))
  78.    { if(!(fin=fopen(pcdname,R_OP))) error(E_FOPEN);
  79.      emulate_seek=0;
  80.    }
  81.   else
  82.    {pcdname="<stdin>";
  83.     emulate_seek=1;
  84.     /* 64Base can't be on stdin - need a suitable error message */
  85.     if (size == S_64Base) error(E_FOPEN);
  86.     fin=stdin;
  87.    }
  88.  
  89.   bufpos=0;
  90.  
  91.  
  92.   checkin();
  93.  
  94.   PLuma=    &Luma;
  95.   PChroma1= &Chroma1; 
  96.   PChroma2= &Chroma2; 
  97.  
  98.   switch(size)
  99.    {
  100.     case S_Base16:  f_1(BaseW/4,BaseH/4,L_Head);
  101.                     break;
  102.  
  103.     case S_Base4:   f_1(BaseW/2,BaseH/2,(L_Head+L_Base16));
  104.                     break;
  105.  
  106.     case S_Base:    f_1(BaseW,BaseH,(L_Head+L_Base16+L_Base4));
  107.                     break;
  108.  
  109.     case S_4Base:   f_4(BaseW*2,BaseH*2,(L_Head+L_Base16+L_Base4));
  110.                     break;
  111.  
  112.     case S_16Base:  f_5(BaseW*4,BaseH*4);
  113.                     break;
  114.  
  115.     case S_64Base:  f_6(BaseW*8,BaseH*8);
  116.                     break;
  117.  
  118.     default: error(E_INTERN); 
  119.    }
  120.  
  121.   close_all();
  122.   exit(0);
  123.  
  124.  }
  125.  
  126.  
  127. static void openoutput(void)
  128. {
  129.     if(ppmname) {
  130.         if ((fout = fopen(ppmname,W_OP)) == NULL)
  131.             error(E_WRITE);
  132.     } else
  133.         fout=stdout;
  134. }
  135.  
  136.  
  137. static void f_1(dim w,dim h,sINT normal)
  138.  {sizeinfo si;
  139.  
  140.   sizecontrol(&si,w,h);
  141.  
  142.   planealloc(PLuma   , w, h);
  143.   planealloc(PChroma1, w, h);
  144.   planealloc(PChroma2, w, h);
  145.  
  146.   PrintPos(normal*SECSIZE);
  147.   SEEK(normal+1);
  148.       
  149.   error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  150.   interpolate(PChroma1);
  151.   interpolate(PChroma2);
  152.  
  153.   si.imvlen=si.rdvlen;
  154.   si.imhlen=si.rdhlen;
  155.   ycctorgb(PLuma,PChroma1,PChroma2);
  156.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  157.  
  158.   openoutput();
  159.   writepicture(fout,&si,PLuma,PChroma1,PChroma2);
  160.  
  161.  }
  162.  
  163.  
  164.  
  165. static void f_4(dim w,dim h,sINT normal)
  166.  {sINT cd_offset;
  167.   sizeinfo si;
  168.   sizecontrol(&si,w,h);
  169.  
  170.   planealloc(PLuma   , w, h);
  171.   planealloc(PChroma1, w, h);
  172.   planealloc(PChroma2, w, h);
  173.  
  174.   PrintPos((L_Head+L_Base16+L_Base4+L_Base)*SECSIZE);
  175.  
  176.   SEEK(L_Head+L_Base16+L_Base4+1);
  177.   error(readplain(&si,-2,PLuma,PChroma1,PChroma2));
  178.   interpolate(PLuma);
  179.   interpolate(PChroma1);
  180.   interpolate(PChroma1);
  181.   interpolate(PChroma2);
  182.   interpolate(PChroma2);
  183.  
  184.  
  185.     cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  186.     SEEK(cd_offset + 4);     readhqt(1);
  187.     SEEK(cd_offset + 5);     decode(&si,1,PLuma,nullplane,nullplane,0);
  188.  
  189.   si.imvlen=si.rdvlen;
  190.   si.imhlen=si.rdhlen;
  191.   ycctorgb(PLuma,PChroma1,PChroma2);
  192.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  193.  
  194.   openoutput();
  195.   writepicture(fout,&si,PLuma,PChroma1,PChroma2);
  196.  
  197.  }
  198.  
  199.  
  200.  
  201.  
  202.  
  203. static void f_5sub(dim w, dim h, sizeinfo *sip,int fak1,int fak2,int fak3)
  204.  {sINT cd_offset;
  205.   
  206.   sizecontrol(sip,w,h);
  207.  
  208.   planealloc(PLuma   , w, h);
  209.   planealloc(PChroma1, w, h);
  210.   planealloc(PChroma2, w, h);
  211.  
  212.   SEEK(L_Head+L_Base16+L_Base4+1);
  213.   error(readplain(sip,fak1,PLuma,PChroma1,PChroma2));
  214.   interpolate(PLuma);
  215.   interpolate(PChroma1);
  216.   interpolate(PChroma1);
  217.   interpolate(PChroma2);
  218.   interpolate(PChroma2);
  219.  
  220.   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  221.   SEEK(cd_offset + 4);       readhqt(1);
  222.   SEEK(cd_offset + 5);       decode(sip,fak2,PLuma,nullplane,nullplane,0);
  223.   interpolate(PLuma);
  224.  
  225.  
  226.   cd_offset=bufpos;
  227.   if(cd_offset % SECSIZE) error(E_POS);
  228.   PrintPos(cd_offset);
  229.   cd_offset/=SECSIZE;
  230.  
  231.   SEEK(cd_offset+12);        readhqt(3);
  232.   SEEK(cd_offset+14);        decode(sip,fak3,PLuma,PChroma1,PChroma2,0);
  233.  
  234.  }
  235.  
  236.  
  237.  
  238.  
  239. static void f_5(dim w,dim h)
  240.  {sizeinfo si;
  241.  
  242.   f_5sub(w,h,&si,-4,-2,1);
  243.  
  244.   interpolate(PChroma1);
  245.   interpolate(PChroma2);
  246.  
  247.   si.imvlen=si.rdvlen;
  248.   si.imhlen=si.rdhlen;
  249.   ycctorgb(PLuma,PChroma1,PChroma2);
  250.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  251.  
  252.   openoutput();
  253.   writepicture(fout,&si,PLuma,PChroma1,PChroma2);
  254.  
  255.  }
  256.  
  257.  
  258.  
  259.  
  260. static void f_6(dim w,dim h)
  261.  {sizeinfo si;
  262.   FILE *ic,*icr[10];
  263.   struct ic_header ic_h;
  264.   struct ic_descr descr[3];
  265.   struct ic_fname names[10];
  266.   struct ic_entry efrom,eto;
  267.   struct file16 namecount,descrcount;
  268.   int i,j,nc,dc;
  269.   char   FN[300];
  270.   int last,ffrom,fto,foff;
  271.  
  272.  
  273.   f_5sub(w,h,&si,-8,-4,-2);
  274.  
  275.   interpolate(PLuma);
  276.   interpolate(PChroma1);
  277.   interpolate(PChroma2);
  278.  
  279.   get_dir64();
  280.  
  281.   sprintf(FN,"%s%c%s",dir64,DIRSEP,"info.ic");
  282.   if(!(ic=fopen(FN,R_OP))) error(E_FOPEN);
  283.   if(fread(&ic_h,sizeof(ic_h),1,ic)<1) error(E_READ);
  284.  
  285.  
  286.  
  287.  
  288.   /******************************************************************************/
  289.   /* layer descriptions */
  290.   /******************************************************************************/
  291.   if(fseek(ic,FILE32(ic_h.off_descr),0)) error(E_READ);
  292.   
  293.   if(fread(&descrcount,sizeof(descrcount),1,ic)<1) error(E_READ);
  294.   dc=FILE16(descrcount);
  295.  
  296.   if(dc != 3) error(E_SEQ);
  297.  
  298.   if(fread(descr,sizeof(descr[0]),dc,ic)<dc) error(E_READ);
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.   /******************************************************************************/
  306.   /* Filenames */
  307.   /******************************************************************************/
  308.   if(fseek(ic,FILE32(ic_h.off_fnames),0)) error(E_READ);
  309.  
  310.   if(fread(&namecount,sizeof(namecount),1,ic)<1) error(E_READ);
  311.   nc=FILE16(namecount);
  312.  
  313.   if((nc<3) || (nc>10)) error(E_SEQ);
  314.  
  315.   if(fread(names,sizeof(names[0]),nc,ic)<nc) error(E_READ);
  316.  
  317. #ifdef SMALLNAMES
  318.   for (i=0;i<nc;i++)
  319.    { 
  320.     {for (j=0;j<sizeof(names[0].fname);j++)
  321.       {if((names[i].fname[j]>= 'A') && (names[i].fname[j]<= 'Z'))
  322.         names[i].fname[j] += 'a'-'A';
  323.       }
  324.     }
  325. #ifdef DEBUG
  326.    fprintf(stderr,"%-*.*s %d\n",sizeof(names[0].fname),sizeof(names[0].fname),names[i].fname, FILE32(names[i].size));
  327. #endif
  328. #endif
  329.    }
  330.  
  331.  
  332.   /******************************************************************************/
  333.   /* Huffman-Tables */
  334.   /******************************************************************************/
  335.   if(fseek(ic,FILE32(ic_h.off_huffman),0)) error(E_READ);
  336.   if(fread(sbuffer,1,sizeof(sbuffer),ic)<5) error(E_READ);
  337.  
  338.   readhqtx(3);
  339.  
  340.  
  341.  
  342.   /******************************************************************************/
  343.   /* Decode it */
  344.   /******************************************************************************/
  345.   for(i=0;i< 3; i++)
  346.    {
  347.     last = si.rdvlen;
  348.  
  349.     if(!i)
  350.      { /* luma */
  351.        if(last>=h) last=h-1;
  352.      }
  353.     else
  354.      { /* chroma */
  355.        last=(last+1)/2;
  356.        if(last>=h/2) last=h/2-1;
  357.      }
  358.  
  359.     if(fseek(ic,FILE32(descr[i].off_pointers),0)) error(E_READ);
  360.     if(fread(&efrom,sizeof(efrom),1,ic)<1) error(E_READ);
  361.  
  362.     if(fseek(ic,FILE32(descr[i].off_pointers)+ 6*4*last,0)) error(E_READ);
  363.     if(fread(&eto  ,sizeof(eto  ),1,ic)<1) error(E_READ);
  364.  
  365.     ffrom=FILE16(efrom.fno);
  366.     fto  =FILE16(eto.fno);
  367.     foff =FILE32(efrom.offset);
  368.  
  369.  
  370. /*    fprintf(stderr,"XXX:  %d  %d  %d\n",ffrom,fto,foff);*/
  371.  
  372.     for(j=ffrom;j<=fto;j++)
  373.      {sprintf(FN,"%s%c%s",dir64,DIRSEP,names[j].fname);
  374.  
  375. #ifdef DEBUG
  376.     fprintf(stderr,"Filename %s\n",FN);
  377. #endif
  378.       if(!(icr[j-ffrom]=fopen(FN,R_OP))) error(E_FOPEN);
  379.      }
  380.     icr[j-ffrom]=0;
  381.  
  382.     if(fseek(icr[0],foff,0)) error(E_READ);
  383.  
  384.     switch (i)
  385.      {case 0:  decodex(icr,0,&descr[0],&si, 1,PLuma,   1);  break;
  386.       case 1:  decodex(icr,1,&descr[1],&si,-2,PChroma1,1);  break;
  387.       case 2:  decodex(icr,2,&descr[2],&si,-2,PChroma2,1);  break;
  388.      }
  389.  
  390.  
  391.     for(j=ffrom;j<=fto;j++)  fclose(icr[j-ffrom]);
  392.  
  393.  
  394.    }
  395.   fclose(ic);
  396.  
  397.   interpolate(PChroma1);
  398.   interpolate(PChroma2);
  399.  
  400.   si.imvlen=si.rdvlen;
  401.   si.imhlen=si.rdhlen;
  402.   ycctorgb(PLuma,PChroma1,PChroma2);
  403.   openoutput();
  404.   writepicture(fout,&si,PLuma,PChroma1,PChroma2);
  405.  
  406.  }
  407.  
  408.  
  409.  
  410.  
  411. #define ASKIP { argc--; argv ++;}
  412.  
  413. static void parseargs(int  argc,char **argv)
  414.  {
  415.   char *opt;
  416.  
  417.   ASKIP;
  418.  
  419.   while((argc>0) && argv[0][0]=='-' && argv[0][1])
  420.    {
  421.     opt= (*argv)+1;
  422.     ASKIP;
  423.  
  424. /**** additional options ****/
  425.  
  426.     if(!strcmp(opt,"i")) 
  427.      { if (!do_info) do_info=1;
  428.        else error(E_ARG);
  429.        continue;
  430.      }
  431.  
  432.  
  433.     if(!strcmp(opt,"m")) 
  434.      { if (!do_melde) do_melde=1;
  435.        else error(E_ARG);
  436.        continue;
  437.      }
  438.  
  439.     if(!strcmp(opt,"pos")) 
  440.      { if (!print_pos) print_pos=1;
  441.        else error(E_ARG);
  442.        continue;
  443.      }
  444.  
  445.  
  446.  
  447.  
  448. /**** Color model options ****/
  449.  
  450.     if(!strcmp(opt,"c0")) 
  451.      { if (corrmode == C_UNSPEC) corrmode = C_LINEAR;
  452.        else error(E_ARG);
  453.        continue;
  454.      }
  455.  
  456.     if(!strcmp(opt,"c-")) 
  457.      { if (corrmode == C_UNSPEC) corrmode = C_DARK;
  458.        else error(E_ARG);
  459.        continue;
  460.      }
  461.  
  462.     if(!strcmp(opt,"c+")) 
  463.      { if (corrmode == C_UNSPEC) corrmode = C_BRIGHT;
  464.        else error(E_ARG);
  465.        continue;
  466.      }
  467.  
  468.  
  469. /**** Resolution options ****/
  470.    
  471.     if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  472.      { if (size == S_UNSPEC) size = S_Base16;
  473.        else error(E_ARG);
  474.        continue;
  475.      }
  476.     if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  477.      { if (size == S_UNSPEC) size = S_Base4;
  478.        else error(E_ARG);
  479.        continue;
  480.      }
  481.     if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  482.      { if (size == S_UNSPEC) size = S_Base;
  483.        else error(E_ARG);
  484.        continue;
  485.      }
  486.     if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  487.      { if (size == S_UNSPEC) size = S_4Base;
  488.        else error(E_ARG);
  489.        continue;
  490.      }
  491.     if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  492.      { if (size == S_UNSPEC) size = S_16Base;
  493.        else error(E_ARG);
  494.        continue;
  495.      }
  496.  
  497.     if((!strcmp(opt,"64Base" )) || (!strcmp(opt,"6"))  || (!strcmp(opt,"4096x6144")))
  498.      { if (size == S_UNSPEC) size = S_64Base;
  499.        else error(E_ARG);
  500. /*
  501.        if(argc<1) error(E_ARG);
  502.        dir64=argv[0];
  503.        ASKIP;
  504. */
  505.        continue;
  506.      }
  507.  
  508.    fprintf(stderr,"Unknown option: -%s\n",opt);
  509.    error(E_ARG);
  510.    }
  511.  
  512.   
  513.   if(argc<1) error(E_ARG);
  514.   pcdname= *argv;
  515.   ASKIP;
  516.  
  517.   if(argc>0) 
  518.    {ppmname= *argv;
  519.     ASKIP;
  520.    }
  521.   
  522.   if(argc>0) error(E_ARG);
  523.  
  524.  
  525.  }
  526. #undef ASKIP
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537. static void checkin(void)
  538.  { 
  539.    if (do_info) 
  540.      { SEEK(1);
  541.        EREADBUF;
  542.      }
  543.  
  544.     if(do_info) druckeid();
  545.  
  546.  }
  547.  
  548.  
  549.  
  550. /************************** file access functions **************/
  551.  
  552. int READ(uBYTE *ptr,int n)
  553.  {int d;
  554.   if(!n) return 1;
  555.   bufpos+=n;
  556.   for(;;)
  557.    {d=fread((char *)ptr,1,n,fin);
  558.     if(d<1) return 0;
  559.     n-=d;
  560.     if (!n) break;
  561.     ptr+=d;
  562.    }
  563.   return 1;
  564.  }
  565.  
  566. static int friss(int n)
  567.  {int d;
  568.  
  569.   while(n>0)
  570.    {
  571.     d= n>sizeof(sbuffer) ? sizeof(sbuffer) : n;
  572.     n-=d;
  573.     if(READ(sbuffer,d) !=1) return 1;
  574.    }
  575.  
  576.   return 0;
  577.  }
  578.  
  579.  
  580. void SEEK(int x)
  581.  {
  582.   x *= SECSIZE;
  583.   if(x<bufpos) error(E_INTERN);
  584.   if(x==bufpos) return;
  585.  
  586.   if(emulate_seek)
  587.    {if(friss(x-bufpos)) error(E_READ);
  588.     if(x!=bufpos) error(E_INTERN);
  589.    }
  590.   else
  591.    {bufpos=x;
  592.     if (fseek(fin,x,0)) error(E_READ);
  593.    }
  594. #ifdef DEBUG
  595.   fprintf(stderr,"S-Position %x\n",bufpos);
  596. #endif
  597.  
  598.  }
  599.  
  600.  
  601.  
  602. int SKIPn(int n)
  603.  {
  604.   if(!n) return 0;
  605.   if(n<0) error(E_INTERN);
  606.     
  607.   if(emulate_seek)
  608.    {return friss(n);
  609.    }
  610.   else
  611.    {bufpos+=n;
  612.     return fseek(fin,(n),1);
  613.    }
  614.  }
  615.  
  616.  
  617.  
  618.  
  619.  
  620. /************************** size control functions **************/
  621.  
  622.  
  623. static void sizecontrol(sizeinfo *si,dim w,dim h)
  624. {
  625.     si->w = si->rdhlen = w;
  626.     si->h = si->rdvlen = h;
  627.     si->imhlen = si->imvlen = 0;
  628. }
  629.  
  630.  
  631.  
  632. /* Thanks to James Pearson for writing get_dir64 */
  633.  
  634. /* finds dir64 from the given input filename 
  635.    Had to change DIRSEP from a string to a character */
  636. static void get_dir64(void)
  637. {
  638.     char    name[32];
  639.     char    *n, *p, *d;
  640.     
  641.     d = dir64;
  642.  
  643.     /* find if input filename includes a path */
  644.     if ((p = strrchr(pcdname,DIRSEP)) == 0)
  645.         p = pcdname;
  646.     else
  647.     {
  648.         /* copy path to start of dir64 */
  649.         n = pcdname;
  650.         p++;
  651.         while (n < p)
  652.             *d++ = *n++;
  653.     }
  654.  
  655.     /* get first part of filename (the bit before .pcd) */
  656.     n = name; 
  657.     while (*p != '.' && *p != '\0')
  658.         *n++ = *p++;
  659.  
  660.     *n = '\0';
  661.  
  662. #ifdef DEBUG
  663.     *d = '\0';
  664.     fprintf(stderr,"Path64: %s\nName64: %s\n",dir64,name);
  665. #endif
  666.  
  667.     /* construct path */
  668. #ifdef SMALLNAMES
  669.     sprintf(d,"..%cipe%c%s%c64base",DIRSEP,DIRSEP,name,DIRSEP);
  670. #else
  671.     sprintf(d,"..%cIPE%c%s%c64BASE",DIRSEP,DIRSEP,name,DIRSEP);
  672. #endif
  673. }
  674.